#include "Renderer/orthographicCamera.h"

#include <glm/gtc/matrix_transform.hpp>

namespace CC
{

    OrthographicCamera::OrthographicCamera(const glm::mat4 &projection)
        : Camera(projection)
    {
    }
    OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top)
        : m_ViewMatrix(1.0f), Camera(glm::ortho(left, right, bottom, top, -1.0f, 1.0f))
    {

        m_ViewProjectionMatrix = GetProjection() * m_ViewMatrix;
    }

    OrthographicCamera::~OrthographicCamera()
    {
    }

    void OrthographicCamera::OnUpdate(Timestep ts)
    {
    }

    void OrthographicCamera::OnEvent(Event &e)
    {
        EventDispatcher dispatcher(e);
		dispatcher.Dispatch<WindowResizeEvent>(std::bind(&OrthographicCamera::OnWindowResize, this, std::placeholders::_1));
    }

    void OrthographicCamera::SetProjection(float left, float right, float bottom, float top)
    {

        glm::mat4 m = glm::ortho(left, right, bottom, top, -1.0f, 1.0f);
        m_ViewProjectionMatrix = m * m_ViewMatrix;
        Camera::SetProjection(m);
    }

    void OrthographicCamera::RecalculateViewMatrix()
    {

        glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_Position) *
                              glm::rotate(glm::mat4(1.0f), glm::radians(m_Rotation), glm::vec3(0, 0, 1));

        m_ViewMatrix = glm::inverse(transform);
        m_ViewProjectionMatrix = GetProjection() * m_ViewMatrix;
    }

    void OrthographicCamera::OnWindowResize(WindowResizeEvent &e)
    {
        if ((float)e.GetWidth() == 0 || (float)e.GetHeight() == 0)
            return;
        SetProjection(0.0, (float)e.GetWidth(), (float)e.GetHeight(), 0.0);
    }
}